#ifndef VSGLOBAL_H
#define VSGLOBAL_H

#include <QString>
#include <QStringList>

#include <QMap>
#include <QMultiMap>

#include <QList>
#include <QLinkedList>

#include <QDebug>
#include <QObject>

#include <assert.h>

typedef QPair<QString, QString> QStringPair;
typedef QMap<QString, QString> QStringMap;

const int c_default_network_port = 39039;
const int c_folder_scan_interval = 10; // seconds
const int c_vctb_id_max_length   = 25;
const QString c_vctb_id_re       = QString("^\\w{1,%1}$").arg(c_vctb_id_max_length);

/** file part size, used for file io caching and serving
    used as minimal size, maximal will be (const_file_part_size * 2 - 1) */
const qint64 c_file_part_size     = 5*1024*1024; // bytes
const int    c_file_part_lifetime = 30000; // milliseconds

const int    c_wit_percent        = 10; // chance to get a witty addition to a response


class vsLog : public QObject
{
    Q_OBJECT

public:
    inline vsLog() : lastTime("gibberish") {}
    static vsLog* instance();
    ~vsLog();

    typedef enum
    {
        info = 0,
        debug,
        error,
        success,
        none
    } msgType;

    static void i(const QString &msg); /// info
    static void d(const QString &msg); /// debug
    static void e(const QString &msg); /// error
    static void s(const QString &msg); /// success
    static void n();                   /// separator (empty line)
    static void r(const QString &msg); /// emit that message once again (should be from history)

    QString     lastTime;
    QStringList history;  /// has type as first char

public slots:
    void addMessage(QString, vsLog::msgType);

signals:
    void message(QString, vsLog::msgType);

protected:
    void reemit(QString msgFromHistory);
};

//------------------------------------------

const QString vsCompanyName = "OrbitalLab";
const QString vsAppName = "VocaSeed";
#define c_def_appsettings_init QSettings::NativeFormat, QSettings::UserScope, vsCompanyName, vsAppName

namespace vsVersion
{
    const int major = 0;
    const int minor = 1;
}

//-----------------------------------------

QString durationToString(qint64 msec);
QString sizeToString(qint64 bytes);


QString genID(); /// generates some ID, and it even may be unique to app!
bool    checkID(const QString &id); /// checks if string may be a correct VocaTube ID

QString urlEncodedName(const QString &name);

/// returns pairs of absolute offset and count, using const_file_part_size
QList<QPair<qint64,qint64> > splitFileByteRange(qint64 from, qint64 count, qint64 fileSize, int &firstIndex);

//-----------------------------------------

QString wittyServeRefusal();

//-----------------------------------------

const qint64 c_byterate_depth_max = 30;
const qint64 c_byterate_depth_min = 3; // used in minimize()

struct byterateCounter
{
protected:
    int histLen;
    int virtValues;
    QLinkedList<qint64> history;

public:
    byterateCounter(int historyLength = c_byterate_depth_max);

    void   add(qint64 bytes);
    void   append(qint64 bytes);
    qint64 rate();

    void   minimize();
};

void setIPService(const QString &ipsT);
QString getIPServiceTemplate();

#endif // VSGLOBAL_H
